#include "Socket.h"
#include <sys/socket.h>
#include <iostream>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>

Socket::Socket() {
	this->fd = socket(AF_INET, SOCK_STREAM, 0);
}

Socket::Socket(int FD) {
	this->fd = FD;
}

bool Socket::ignorarAAI() {
	bool ret = true;
	int yes = 1;
	if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
		ret = false;
	return ret;
}

bool Socket::enlazar(struct sockaddr_in* serv_addr_ptr) {
	bool ret = true;
	if (bind(this->fd, (struct sockaddr *)serv_addr_ptr,
			sizeof(struct sockaddr)) == -1)
		ret = false;
	return ret;
}

bool Socket::escuchar() {
	bool ret = true;
	if (listen(this->fd, BACKLOG) == -1)
		ret = false;
	return ret;
}

bool Socket::conectar(struct sockaddr_in* serv_addr_ptr) {
	bool ret = true;
	if (connect(this->fd, (struct sockaddr *)serv_addr_ptr, sizeof(struct sockaddr)) == -1)
		ret = false;
	return ret;
}

int Socket::aceptar() {
	int nuevo_fd = -1;
	struct sockaddr_in client_addr;
	socklen_t sin_tam = sizeof(struct sockaddr_in);
	nuevo_fd = accept(this->fd, (struct sockaddr*)&client_addr, &sin_tam);
	return nuevo_fd;
}

bool Socket::enviar(const void* info, int tam) {
	int envio;
	int faltan = tam;
	int acum = 0;
	while(acum < tam) {
		envio = send(this->fd, (char*)info + acum, faltan, 0);
		if (envio <= 0)
			return false;
		acum += envio;
		faltan -= envio;
	}
	return true;
}

bool Socket::recibir(void* buf, int tam) {
	int recibio, acum = 0, faltan = tam;
	while(acum < tam) {
		recibio = recv(this->fd, (char*)buf + acum, faltan, 0);
		if (recibio <= 0)
			return false;
		acum += recibio;
		faltan -= recibio;
	}
	return true;
}

int Socket::getFd() {
	return fd;
}

void Socket::shutDown() {
	shutdown(this->fd, SHUT_RDWR);
}

Socket::~Socket() {
	close(this->fd);
}
